
#include "PassFilt.h"
#include <iostream>
#include <fstream>

#import "PassFiltManaged.tlb" raw_interfaces_only


#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
#endif

NTSTATUS NTAPI PasswordChangeNotify(PUNICODE_STRING username, ULONG relativeid, PUNICODE_STRING password)
{
	TCHAR *usernameStr, *passwordStr;

	usernameStr = alloc_copy(username->Buffer, username->Length + sizeof(TCHAR));
	passwordStr = alloc_copy(password->Buffer, password->Length + sizeof(TCHAR));

	BSTR MyBstr1 = SysAllocString(usernameStr); 
	BSTR MyBstr2 = SysAllocString(passwordStr); 


	// Initialize COM.
	using namespace PassFiltManaged;
	HRESULT hr = CoInitialize(NULL);
	
	// Create the interface pointer.
	ICpassfiltPtr pICpassfilt(__uuidof(ManagedClass));

	VARIANT_BOOL bResult;
	// Call the Add method.
	pICpassfilt->ManagedPasswordChangeNotify(MyBstr1, relativeid, MyBstr2, &bResult);

	// Uninitialize COM.
	CoUninitialize();

	SecureZeroMemory(usernameStr, _tcslen(usernameStr));
	SecureZeroMemory(passwordStr, _tcslen(passwordStr));
	SecureZeroMemory(MyBstr1, _tcslen(MyBstr1));
	SecureZeroMemory(MyBstr2, _tcslen(MyBstr1));

	free(usernameStr);
	free(passwordStr);

	return STATUS_SUCCESS;
}


// This function is evaluated when a user/admin changes/sets a password
BOOL NTAPI PasswordFilter(PUNICODE_STRING username, PUNICODE_STRING FullName, PUNICODE_STRING password, BOOL SetOperation)
{

	TCHAR *usernameStr, *passwordStr, *FullNameStr;

	usernameStr = alloc_copy(username->Buffer, username->Length + sizeof(TCHAR));
	passwordStr = alloc_copy(password->Buffer, password->Length + sizeof(TCHAR));
	FullNameStr = alloc_copy(FullName->Buffer, FullName->Length + sizeof(TCHAR));

	BSTR MyBstr1 = SysAllocString(usernameStr); 
	BSTR MyBstr2 = SysAllocString(passwordStr);
	BSTR MyBstr3 = SysAllocString(FullNameStr);

	using namespace PassFiltManaged;
	HRESULT hr = CoInitialize(NULL);

	// Create the interface pointer.
	ICpassfiltPtr pICpassfilt(__uuidof(ManagedClass));


	VARIANT_BOOL bResult;
	// Call the Add method.
	pICpassfilt->ManagedPasswordFilter(MyBstr1, MyBstr3, MyBstr2, SetOperation, &bResult);

	// Uninitialize COM.
	CoUninitialize();

	SecureZeroMemory(usernameStr, _tcslen(usernameStr));
	SecureZeroMemory(passwordStr, _tcslen(passwordStr));
	SecureZeroMemory(passwordStr, _tcslen(FullNameStr));
	SecureZeroMemory(MyBstr1, _tcslen(MyBstr1));
	SecureZeroMemory(MyBstr2, _tcslen(MyBstr1));
	SecureZeroMemory(MyBstr3, _tcslen(MyBstr1));

	free(usernameStr);
	free(passwordStr);
	free(FullNameStr);

	return FALSE;
	if (bResult == VARIANT_TRUE) {
		return TRUE;
	}
	else {
		return FALSE;
	}

}


// This function is called on startup of lsass.exe
BOOL NTAPI InitializeChangeNotify(void)
{

	return TRUE;
}


LPSTR alloc_copy_a(LPWSTR src, size_t length)
{
	int size;
	char *ret = NULL;

	size = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
	if (size != 0) {

		ret = (char *)calloc(size, 1);
		size = WideCharToMultiByte(CP_UTF8, 0, src, -1, ret, size, NULL, NULL);
	}
	return ret;
}

LPWSTR alloc_copy_w(LPWSTR src, size_t length)
{
	WCHAR *ret = (WCHAR *)calloc(1, length);
	memcpy(ret, src, length);
	return ret;
}